﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using PostSharp.CodeModel;
using PostSharp.Collections;

namespace MicroContainer.CompileTime.Generators
{
   class StaticContainerGenerator : ICodeGenerator
   {
      public void Generate(CodeGenerationContext ctx)
      {
         FieldDefDeclaration soleInstance = new FieldDefDeclaration();
         ctx.ContainerType.Fields.Add(soleInstance);
         soleInstance.Attributes = FieldAttributes.Private | FieldAttributes.Static;
         soleInstance.FieldType = ctx.ContainerType;            
         soleInstance.Name = "_soleInstance";

         MethodDefDeclaration staticCnstructor = ctx.ContainerType.Methods.GetOneByName(".cctor");
         MethodDefDeclaration instanceCnstructor = ctx.ContainerType.Methods.GetOneByName(".ctor");

         InstructionBlock block = staticCnstructor.MethodBody.RootInstructionBlock;
         InstructionWriter writer = new InstructionWriter();
         InstructionSequence seq = staticCnstructor.MethodBody.CreateInstructionSequence();
         block.AddInstructionSequence(seq, NodePosition.After, null);
         writer.AttachInstructionSequence(seq);
         
         writer.EmitInstructionMethod(OpCodeNumber.Newobj, instanceCnstructor);
         writer.EmitInstructionField(OpCodeNumber.Stsfld, soleInstance);

         writer.DetachInstructionSequence();

         staticCnstructor.MethodBody.MaxStack = MethodBodyDeclaration.RecomputeMaxStack;
      }
   }
}
